﻿/* AgileFx Version 1.0
 * An open-source framework for rapid development of applications and services using Microsoft.net
 * Developed by: AgileHead
 * Website: www.agilefx.org
 * This component is licensed under the terms of the Apache 2.0 License.
 */

using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;

using AgileFx.EF;
using AgileFx.EF.ModificationTypes;

namespace AgileFx.MVC
{
    public class DefaultController<T> : Controller where T : DefaultView, new()
    {
        Action<T> defaultViewUpdate;

        //This hides the Dictionary. Remove?
        public new object ViewData = null;

        protected void UpdateDefaultView(Action<T> func)
        {
            this.defaultViewUpdate += func;
        }

        protected new ViewResult View()
        {
            T viewData = new T();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            return base.View(viewData);
        }

        protected new ViewResult View(string viewName)
        {
            T viewData = new T();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            return base.View(viewName, viewData);
        }

        protected ViewResult View(Action<T> updateView)
        {
            T viewData = new T();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            updateView(viewData);
            return base.View(viewData);
        }

        protected ViewResult View(string viewName, Action<T> updateView)
        {
            T viewData = new T();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            updateView(viewData);
            return base.View(viewName, viewData);
        }

        protected ViewResult View<X>() where X : T, new()
        {
            X viewData = new X();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            return base.View(viewData);
        }

        protected ViewResult View<X>(Action<X> specializedViewUpdate) where X : T, new()
        {
            X viewData = new X();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            specializedViewUpdate(viewData);
            return base.View(viewData);
        }

        protected ViewResult View<X>(string viewName) where X : T, new()
        {
            X viewData = new X();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            return base.View(viewName, viewData);
        }

        protected ViewResult View<X>(string viewName, Action<X> specializedViewUpdate) where X : T, new()
        {
            X viewData = new X();
            if (defaultViewUpdate != null)
                defaultViewUpdate(viewData);
            specializedViewUpdate(viewData);
            return base.View(viewName, viewData);
        }

        protected int Pager_GetStart(int? page, int pageSize)
        {
            return pageSize * (page.GetValueOrDefault(1) - 1) + 1;
        }

        protected string GetString(string code)
        {
            return I18n.GetString(code);
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            try
            {
                var msgCode = Request["message"] as string;
                if (!msgCode.Empty()) UpdateDefaultView(v => v.MessageCode = msgCode);
            }
            catch { }
        }

        public EntityAddition<TElement, TElement> AddEntity<TElement>(Action<TElement> entityUpdate, params IModification[] entityFieldUpdates)
            where TElement : EntityObject, new()
        {
            return Modification.AddEntity<TElement>(entityUpdate, entityFieldUpdates);
        }

        public EntityUpdation<TElement, TElement> UpdateEntity<TElement>(Action<TElement> entityUpdate,
            params IModification[] entityFieldUpdates) where TElement : EntityObject, new()
        {
            return Modification.UpdateEntity<TElement>(entityUpdate, entityFieldUpdates);
        }
    }
}
